package cn.czg.cms.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.util.AttributeKey;

import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

public class WebSocketHandshakeHandler extends ChannelInboundHandlerAdapter {
    private final NettyChannelManager nettyChannelManager;

    public WebSocketHandshakeHandler(NettyChannelManager nettyChannelManager) {
        this.nettyChannelManager = nettyChannelManager;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
            // 握手成功事件，开始绑定用户
            String uri = ctx.channel().attr(AttributeKey.valueOf("uri")).get().toString();
            // 或从 ctx.channel().remoteAddress() / 请求头里获取 userId
            String userId = extractUserIdFromUri(uri);

            nettyChannelManager.add(Long.valueOf(Objects.requireNonNull(userId)), ctx.channel());

            System.out.println("用户 " + userId + " 已绑定连接，channelId: " + ctx.channel().id());
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    private String extractUserIdFromUri(String uriStr) {
        try {
            URI uri = new URI(uriStr);
            String query = uri.getQuery(); // 获取 query 部分，比如 userId=xxx&...
            if (query == null || query.isEmpty()) {
                return null;
            }
            String[] pairs = query.split("&");
            for (String pair : pairs) {
                String[] kv = pair.split("=", 2);
                if (kv.length == 2 && "userId".equals(kv[0])) {
                    // URL 解码
                    return URLDecoder.decode(kv[1], StandardCharsets.UTF_8);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}


